#!/usr/bin/perl -I ./thirds -w
# Author: lilongen (microli@sz.webex.com, lonli@cisco.com, lilongen@163.com)
# Date: 06/11/2010

use strict;
use English;
use Data::Dumper;
use CGI;
use JSON;
use Assistor;

my $WC = {
	GET_OVERALL 	=> "GET_OVERALL",
	GET_MODULES 	=> "GET_MODULES",
	GET_XML_FILES 	=> "GET_XMLS",
	GET_CFG 		=> "GET_CFG",
	DEL_XML_FILE 	=> "DEL_XML_FILE",
	UP_XML_FILE 	=> "UP_XML_FILE",
	GENERATE 	    => "GENERATE",
	GET_PROGRESS    => "GET_PROGRESS"
};

sub main();

sub parseParams();
sub constructOperatorCMDLine();
sub addArgu($$);

sub deleteCfgFile();
sub uploadFile();

my $q = new CGI;
my $pms = {};
my $cfg = $q->param("cfg") || "";
my $T_SNAP = $q->param("T_SNAP") || "";
my $assistor = new Assistor($cfg, $T_SNAP);	

exit main();

sub main() {
    my $cmd = $q->param("cmd");
    my $contentType = ($cmd ne $WC->{UP_XML_FILE}) ? "application/json" : "text/html";
    
    print "Content-type: $contentType\n\n";

	my $ret = {};
	my $json = new JSON;

	if (!$cmd) {
        $ret->{error} = 1;
        $ret->{id} = "";
        $ret->{desc} = "NO_COMMAND"; 
	    
		print $json->pretty->encode($ret);
		
		return 1;
	}
	
	if ($cmd eq $WC->{GENERATE}) {
        parseParams();
        $pms->{T_SNAP} = $assistor->get_time_snapshot();
        $pms->{ARGUS} = ""; 
        my $cmdLine = constructOperatorCMDLine();

       	system($cmdLine);
       	
       	$ret->{T_SNAP} = $pms->{T_SNAP};
	} elsif ($cmd eq $WC->{GET_PROGRESS}) {
        my $fileProgress    = $assistor->get_operate_log_file();
        my $fileContent = "-1000";
        
        if (-e $fileProgress) {
        	$fileContent = $assistor->read_whole_file($fileProgress);
        	my $tail512 = substr($fileContent, -512);
        
        	if (index($tail512, "<DONE></DONE>") != -1) {
        		my $cmd = "mv $fileProgress $fileProgress" . "--";
        		print `$cmd`;    
        	}
        	$fileContent =~ s|\n|<br/>|g;
        }
        
        $ret->{content} = $fileContent;
	} elsif ($cmd eq $WC->{GET_OVERALL}) {
		$assistor->getModules();
		$ret->{CFG_FILE} = substr($assistor->{CONFIG_FILE}, length("config/"));
		$ret->{CFG_FILES} = $assistor->{CFG_FILES};
		$ret->{MODULES} = $assistor->{modules4UI};
	} elsif ($cmd eq $WC->{GET_MODULES}) {
	    my $cfg = $q->param("cfg");
	    $assistor->set_config_file($cfg);
		$assistor->getModules();
		$ret->{MODULES} = $assistor->{modules4UI};
	} elsif ($cmd eq $WC->{SAVE_CFG}) {
		$assistor->getModules();
		$ret = $assistor->{modules4UI};
	} elsif ($cmd eq $WC->{DEL_XML_FILE}) {
	    $pms->{cfg} = $q->param("cfg");
	    $pms->{cfgPwd} = $q->param("cfgPwd");	    
	    
    	my $error = deleteCfgFile();
    	
    	if ($error == 0) {
            $ret->{error} = 0;
            $ret->{id} = "";
            $ret->{desc} = ""; 
    	} else {
            $ret->{error} = 1;
            $ret->{id} = "";
            $ret->{desc} = ""; 
    	}	    
	} elsif ($cmd eq $WC->{UP_XML_FILE}) {
	    $pms->{hUploadedFile} = $q->param("uploadedFile");
	    $pms->{cfgPwd} = $q->param("cfgPwd");
	        	
        my $retCode = uploadFile();
        
        if ($retCode eq "E1") {
            $ret->{error} = 1;
            $ret->{id} = "";
            $ret->{desc} = "Upload failed!"; 
        } elsif ($retCode eq "E2") {
            $ret->{error} = 1;
            $ret->{id} = "PWD_NOT_MATCHED";
            $ret->{desc} = "File write-password not right, upload failed!";
        } elsif ($retCode eq "new") {
            $ret->{error} = 0;
            $ret->{id} = "NEW";
            $ret->{desc} = "Upload successfully!";
        } elsif ($retCode eq "update") {
            $ret->{error} = 0;
            $ret->{id} = "UPDATE";
            $ret->{desc} = "Update successfully!";            
        }
    }	    
    
	print $json->pretty->encode($ret);

	return 0;	
}

sub deleteCfgFile() {
	my $pwdMatched = 0;
    my $PWD_FILE = "config/CFG_PWD";
	my $cfgPwdLine = "$pms->{cfg}=$pms->{cfgPwd}";
    if (-e $PWD_FILE) {
	    my $pwdFileContent = $assistor->read_whole_file($PWD_FILE);
		$pwdMatched = index($pwdFileContent, "$cfgPwdLine\n") != -1;
	}
	
	if ($pwdMatched) {
		my $file = "config/$pms->{cfg}";
    	my $bkfile = $file . "-delete";
		print `mv -f $file $bkfile`;
	
		$cfgPwdLine =~ s|/|\\/|g;
		print `sed -i /$cfgPwdLine/d $PWD_FILE`;
		
		return 0;
  	} else {
		return 1;
	}
}


sub uploadFile() {
    my $configs = $assistor->{CFG_FILES};
    my $cfgsString = ";" . join(";", @{$configs}) . ";";
	
	my $pwdMatched = 0;
	my $fileName = substr($pms->{hUploadedFile}, rindex($pms->{hUploadedFile}, '/') + 1);
	$fileName =~ s/^.*[\\\/]//g;
	$fileName =~ s/\s//g;	
	my $cfgPwdLine = "$fileName=$pms->{cfgPwd}\n";
    my $PWD_FILE = "config/CFG_PWD";
    if (-e $PWD_FILE) {
	    my $pwdFileContent = $assistor->read_whole_file($PWD_FILE);
	    if (index($pwdFileContent, $cfgPwdLine) != -1) {
	    	$pwdMatched = 1;
	    }
		#if (index($pwdFileContent, $pms->{hUploadedFile}) != -1) {
		#	if (index($pwdFileContent, $cfgPwdLine) != -1) {
		#		$pwdMatched = 1;
		#	} else {
		#		$pwdMatched = 0;
		#	}
		#} else {
		#	$pwdMatched = 1;
		#}
	} 

	my $file = "config/$fileName";
	my $fileExist = index($cfgsString, ";" . $fileName . ";") != -1;
	
	if ($fileExist && $pwdMatched) {
    	my $bkfile = substr($fileName, 0, -4) . ".xml." . "-" . $assistor->get_time_serial();
    	$bkfile = "config/$bkfile";
    	
    	print `mv $file $bkfile`;
    	
  	}
    
	if (!$fileExist || ($fileExist && $pwdMatched)) {
	    my $OUT;
	    if (!open($OUT, ">", $file)) {
	       return "E1";   
	    }
	    binmode($OUT);
	    while (my $ret = read($pms->{hUploadedFile}, my $buffer, 1024)) {
	       print $OUT $buffer;
	    }
	    close($OUT);
	} else {
		return "E2";
	}
	
	if (!$fileExist) {	    
	    my $HPWD;
	    if (!open($HPWD, ">>", $PWD_FILE)) {
	    	return "E1";
	    }
	    print $HPWD $cfgPwdLine;
	    close($HPWD);
  	}
  	
    if ($fileExist) {
    	return "update";	
    } else {
    	return "new";
    }
}


sub parseParams(){
    $pms->{cfg} 	= $q->param("cfg");
    $pms->{mode} 	= $q->param("mode");
    $pms->{mids} 	= $q->param("mids");
    $pms->{GO} 	    = $q->param("opts");#global options
    $pms->{filter}  = $q->param("filter");
   
    if ($pms->{mode} == 0) {
	    $pms->{rev} 	= $q->param("rev");
	    $pms->{date} 	= $q->param("date");
	    $pms->{wids} 	= $q->param("wids");    	
    } else {
	    $pms->{r1} 		= $q->param("r1");
	    $pms->{r2} 		= $q->param("r2");
	    $pms->{d1} 		= $q->param("d1");
	    $pms->{d2} 		= $q->param("d2");
	    $pms->{rd1b} 	= $q->param("rd1b");
	    $pms->{rd2b} 	= $q->param("rd2b");
	    $pms->{bb} 		= $q->param("bb");
	    $pms->{dfAgainst} = $q->param("dfAgainst");
    }
}

sub constructOperatorCMDLine() {
	addArgu("-T", $pms->{T_SNAP});
	addArgu("-f", $pms->{cfg});
	addArgu("-R", $pms->{mode});
	addArgu("-m", $pms->{mids});
	addArgu("-GO",$pms->{GO});
		
	if ($pms->{mode} == 0) {
		addArgu("-r", $pms->{rev});
		addArgu("-d", $pms->{date});
		addArgu("-w", $pms->{wids});		
	} else {
		addArgu("-r1", $pms->{r1});
		addArgu("-r2", $pms->{r2});
		addArgu("-D1", $pms->{d1});
		addArgu("-D2", $pms->{d2});
		
		addArgu("-DFA", $pms->{dfAgainst});
		addArgu("-rd1b", $pms->{rd1b});
		addArgu("-rd2b", $pms->{rd2b});
		addArgu("-bb", $pms->{bb});
	}

	addArgu("-FILTER", $pms->{filter});
	addArgu("-FC", 1);#from cgi
	
	return "perl -w ccv.pl $pms->{ARGUS} 2>/dev/null 1>/dev/null & ";
}

sub addArgu($$) {
	my $indicator = $_[0];
	my $val = $_[1];
	
	$pms->{ARGUS} .= " \"$indicator$val\"";
}

